import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

import org.apache.commons.lang.ArrayUtils;


public class Ex1_7 {

	public ArrayList<int[]> permutations;
	public TreeSet<String>  mutationsK;
	public HashMap<String, Integer> mutations;

	/**
	 * Constructor
	 */
	public Ex1_7() {
		permutations = new ArrayList<int[]>();
		mutationsK = new TreeSet<String>();
		mutations = new HashMap<String, Integer>();
	}


	public void mutateK(String seq, int[] perm) {
		String sout ;		
		char[] nucs = {'A','T','G','C'};
		for (char c : nucs) {		
			sout = seq.substring(0, perm[0]) + c + seq.substring(perm[0]+1);						
			if (perm.length > 1) {				
				mutateK(sout, ArrayUtils.remove(perm, 0).clone());				
			} else {
				mutationsK.add(sout);
			}
		}
	}

	
	
	
	
	

	/**
	 * Get combinations
	 * @param k k-mer length
	 * @param d differences
	 */
	public void generatePerm(int k, int[] c) throws Exception {
		//System.out.println(Arrays.toString(c));
		if (c!= null) {
			permutations.add(c.clone());
		}
		int col = -1;
		// get last incrementable
		for (int i= c.length -1 ;i>=0;i--) {
			if (c[i] < k- (c.length - i)  ) {
				col = i;
				break;
			}
			// we reach start of array and we didnt find incrementable: exit 
			if (i == 0) {
				return;
			}	
		}		
		// reset array
		int l = c[col];
		for (int j=col;j<c.length;j++) {			
			l = l + 1;
			c[j] = l;
		}						
		generatePerm(k,c);		
	}


	public static void main(String[] args) {
		try {
			// input values
			//String cad = "ACGTTGCATGTCGCATGATGCATGAGAGCT";
			
			String cad =   KmerCounter.readFile("C:\\Users\\josemfer\\Downloads\\dataset_8_4.txt").trim();			
			
			int d = 2;
			int k = 8;

			// generate input array for generatePerm method
			int[] seed = new int[d];
			for (int i=0;i<d;i++) {
				seed[i] = i;
			}

			// create object and generate permutations			
			Ex1_7 ex = new Ex1_7();
			ex.generatePerm(k, seed);

			// read input string and get k-mers
			for (int i=0; i< cad.length() - k + 1;i++) {
				String kmer = cad.substring(i,i+k);		

				// reset k-mer mutations
				ex.mutationsK.clear();

				// iterate permutations
				for (int[] perm : ex.permutations) {					
					// generate mutations
					ex.mutateK(kmer,perm);	
				}	

				// save mutations and increment counter, if exists
				for (String m : ex.mutationsK) {
					if (ex.mutations.containsKey(m)) {							
						ex.mutations.put(m, ex.mutations.get(m) + 1);
					} else {						
						ex.mutations.put(m, 1);
					}
				}		
			} // kmer level

			// order hashmap by value
			int maxV = 0;
			ArrayList<String> muts = new ArrayList<String>();
			for (Map.Entry<String, Integer> entry : ex.mutations.entrySet()) {
				String key = entry.getKey();
				Integer value = entry.getValue();
				if (value > maxV) {
					muts.clear();
					muts.add(key);
					maxV = value;
				} else if (value == maxV) {
					muts.add(key);
				}
			} 
			
		System.out.println(muts.toString().replaceAll("\\[", "").
								replaceAll("\\]","").replaceAll(","," "));	
					
		System.out.println("stop");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
